static char unicsv_detect;
static int llprec;
-static arglist_t unicsv_args[] = {
+static arglist_t unicsv_args[] = {
{"datum", &opt_datum, "GPS datum (def. WGS 84)",
- "WGS 84", ARGTYPE_STRING, ARG_NOMINMAX},
+ "WGS 84", ARGTYPE_STRING, ARG_NOMINMAX},
{"grid", &opt_grid, "Write position using this grid.",
NULL, ARGTYPE_STRING, ARG_NOMINMAX},
- {"utc", &opt_utc, "Write timestamps with offset x to UTC time",
+ {"utc", &opt_utc, "Write timestamps with offset x to UTC time",
NULL, ARGTYPE_INT, "-23", "+23"},
- {"format", &opt_format, "Write name(s) of format(s) from input session(s)",
+ {"format", &opt_format, "Write name(s) of format(s) from input session(s)",
NULL, ARGTYPE_BOOL, ARG_NOMINMAX},
- {"filename", &opt_filename, "Write filename(s) from input session(s)",
+ {"filename", &opt_filename, "Write filename(s) from input session(s)",
NULL, ARGTYPE_BOOL, ARG_NOMINMAX},
- {"prec", &opt_prec, "Precision of numerical coordinates (no grid set)",
+ {"prec", &opt_prec, "Precision of numerical coordinates (no grid set)",
"6", ARGTYPE_INT | ARGTYPE_HIDDEN, "0", "15"},
ARG_TERMINATOR };
unicsv_strrcmp(const char *s1, const char *s2)
{
int l1, l2;
-
+
l1 = strlen(s1);
l2 = strlen(s2);
if ((l1 - l2) >= 0)
return 1; /* false */
}
+static int
+unicsv_parse_gc_id(const char *str)
+{
+ int res = 0;
+
+ if (str && (str[0] == 'G') && (str[1] == 'C')) {
+ int base;
+ char cx;
+
+ str += 2;
+ if (strlen(str) > 4) base = 31;
+ else base = (*str < 'G') ? 16 : 31;
+
+ while ((cx = *str++)) {
+ int num;
+
+ if ((cx >= '0') && (cx <= '9')) num = cx - '0';
+ else if ((cx >= 'A') && (cx <= 'Z')) num = cx - 'A' + 10;
+ else break;
+
+ res = (res * base) + num;
+ }
+ if (base == 31) res -= 411120;
+ }
+ return res;
+}
+
// static int unicsv_parse_time(const char *str, int *msec, time_t *date);
static time_t
char sep[2];
struct tm tm;
int lconsumed = 0;
-
+
memset(&tm, 0, sizeof(tm));
ct = sscanf(str, "%d%1[-.//]%d%1[-.//]%d%n", &p1, sep, &p2, sep, &p3, &lconsumed);
if (consumed && lconsumed) {
}
fatal(MYNAME ": Could not parse date string (%s).\n", str);
}
-
+
if ((p1 > 99) || (sep[0] == '-')) { /* Y-M-D (iso like) */
tm.tm_year = p1;
tm.tm_mon = p2;
}
fatal(MYNAME ": Could not parse date string (%s).\n", str);
}
-
+
tm.tm_year -= 1900;
tm.tm_mon -= 1;
-
+
return mkgmtime(&tm);
}
*date = ldate;
}
}
-
+
ct = sscanf(str, "%d%1[.://]%d%1[.://]%d%lf", &hour, sep, &min, sep, &sec, &ms);
is_fatal(ct < 5, MYNAME ": Could not parse time string (%s).\n", str);
if (ct == 6) {
static status_type
unicsv_parse_status(const char *str)
{
- if ((case_ignore_strcmp(str, "true") == 0) ||
+ if ((case_ignore_strcmp(str, "true") == 0) ||
(case_ignore_strcmp(str, "yes") == 0) ||
(*str == '1')) return status_true;
- else if ((case_ignore_strcmp(str, "false") == 0) ||
- (case_ignore_strcmp(str, "no") == 0) ||
+ else if ((case_ignore_strcmp(str, "false") == 0) ||
+ (case_ignore_strcmp(str, "no") == 0) ||
(*str == '0')) return status_false;
else return status_unknown;
}
int i, column;
const cet_cs_vec_t *ascii = &cet_cs_vec_ansi_x3_4_1968; /* us-ascii */
- /* Convert the entire header to lower case for convenience.
+ /* Convert the entire header to lower case for convenience.
* If we see a tab in that header, we decree it to be tabsep.
*/
- unicsv_fieldsep = ",";
+ unicsv_fieldsep = ",";
for (s = ibuf; *s; s++) {
if (*s == '\t') {
unicsv_fieldsep = "\t";
for (s = ibuf; *s; s++) {
*s = tolower(*s);
}
-
+
/* convert the header line into native ascii */
if (global_opts.charset != ascii) {
buf = cet_str_any_to_any(ibuf, global_opts.charset, ascii);
column = -1;
while ((s = csv_lineparse(ibuf, unicsv_fieldsep, "\"", 0))) {
-
+
field_t *f = &fields_def[0];
-
+
ibuf = NULL;
column++;
unicsv_fields_tab_ct++;
s = lrtrim(s);
-
+
if (column % 4 == 0) {
int sz = (column + 4) * sizeof(*unicsv_fields_tab);
if (column == 0) unicsv_fields_tab = xmalloc(sz);
}
if ((! f->name) && global_opts.debug_level)
warning(MYNAME ": Unhandled column \"%s\".\n", s);
-
+
/* handle some special items */
if (f->type == fld_altitude) {
if (UNICSV_CONTAINS("ft") || UNICSV_CONTAINS("feet")) {
unicsv_altscale = 1.0;
unicsv_depthscale = 1.0;
unicsv_proximityscale = 1.0;
-
+
unicsv_fields_tab = NULL;
unicsv_fields_tab_ct = 0;
unicsv_data_type = global_opts.objective;
unicsv_datum_idx = gt_lookup_datum_index(opt_datum, MYNAME);
fin = gbfopen(fname, "rb", MYNAME);
-
+
if ((c = gbfgetstr(fin)))
unicsv_fondle_header(c);
else
column = -1;
while ((s = csv_lineparse(ibuf, unicsv_fieldsep, "\"", 0))) {
-
+
if (column > unicsv_fields_tab_ct) break; /* ignore extra fields on line */
ibuf = NULL;
switch(unicsv_fields_tab[column]) {
-
+
case fld_latitude:
human_to_dec( s, &wpt->latitude, &wpt->longitude, 1 );
wpt->latitude = wpt->latitude * ns;
break;
-
+
case fld_longitude:
human_to_dec( s, &wpt->latitude, &wpt->longitude, 2 );
wpt->longitude = wpt->longitude * ew;
break;
-
+
case fld_shortname:
wpt->shortname = xstrdup(s);
break;
-
+
case fld_description:
wpt->description = xstrdup(s);
break;
case fld_utm_zone:
utm_zone = atoi(s);
break;
-
+
case fld_utm_easting:
utm_easting = atof(s);
break;
-
+
case fld_utm_northing:
utm_northing = atof(s);
break;
-
+
case fld_utm_zone_char:
utm_zc = toupper(s[0]);
break;
-
+
case fld_utm:
parse_coordinates(s, unicsv_datum_idx, grid_utm,
&wpt->latitude, &wpt->longitude, MYNAME);
don't convert a second time */
src_datum = DATUM_WGS84;
break;
-
+
case fld_bng_zone:
strncpy(bng_zone, s, sizeof(bng_zone));
strupper(bng_zone);
case fld_bng_easting:
bng_easting = atof(s);
break;
-
+
case fld_swiss:
parse_coordinates(s, DATUM_WGS84, grid_swiss,
&wpt->latitude, &wpt->longitude, MYNAME);
WAYPT_SET(wpt, course, atof(s));
if (unicsv_detect) unicsv_data_type = trkdata;
break;
-
+
case fld_temperature:
d = atof(s);
if (fabs(d) < 999999) WAYPT_SET(wpt, temperature, d);
if (parse_distance(s, &d, unicsv_depthscale, MYNAME))
WAYPT_SET(wpt, depth, d);
break;
-
+
case fld_symbol:
wpt->icon_descr = xstrdup(s);
wpt->wpt_flags.icon_descr_is_dynamic = 1;
break;
-
+
case fld_iso_time:
is_localtime = 2; /* fix result */
wpt->creation_time = xml_parse_time(s, &wpt->microseconds);
}
break;
- case fld_date:
+ case fld_date:
if ((is_localtime < 2) && (date < 0)) {
date = unicsv_parse_date(s, NULL);
is_localtime = 1;
}
break;
-
+
case fld_year:
ymd.tm_year = atoi(s);
break;
switch(unicsv_fields_tab[column]) {
- case fld_gc_id:
- if ((s[0] == 'G') && (s[1] == 'C')) sscanf(s, "GC%x", &gc_data->id);
- else gc_data->id = atoi(s);
+ case fld_gc_id:
+ gc_data->id = atoi(s);
+ if (gc_data->id == 0) gc_data->id = unicsv_parse_gc_id(s);
break;
case fld_gc_type: gc_data->type = gs_mktype(s); break;
case fld_gc_container: gc_data->container = gs_mkcont(s); break;
waypt_free(wpt);
return;
}
-
+
if (is_localtime < 2) { /* not fixed */
if ((time >= 0) && (date >= 0)) {
time_t t = date + time;
-
+
if (is_localtime) {
struct tm tm;
tm = *gmtime(&t);
else ymd.tm_year += 1900;
}
ymd.tm_year -= 1900;
-
+
if (ymd.tm_mon == 0) ymd.tm_mon = 1;
if (ymd.tm_mday == 0) ymd.tm_mday = 1;
-
+
ymd.tm_mon--;
if (opt_utc)
wpt->creation_time = mkgmtime(&ymd);
if (msec >= 0)
wpt->microseconds = msec;
-
+
if (opt_utc)
wpt->creation_time += atoi(opt_utc) * SECONDS_PER_HOUR;
}
-
+
/* utm/bng/swiss can be optional */
if ((wpt->latitude == unicsv_unknown) && (wpt->longitude == unicsv_unknown)) {
src_datum = DATUM_WGS84; /* don't convert afterwards */
}
}
-
- if ((src_datum != DATUM_WGS84) &&
+
+ if ((src_datum != DATUM_WGS84) &&
(wpt->latitude != unicsv_unknown) && (wpt->longitude != unicsv_unknown)) {
double alt;
- GPS_Math_Known_Datum_To_WGS84_M(wpt->latitude, wpt->longitude, (double) 0.0,
+ GPS_Math_Known_Datum_To_WGS84_M(wpt->latitude, wpt->longitude, (double) 0.0,
&wpt->latitude, &wpt->longitude, &alt, src_datum);
}
}
}
-static void
+static void
unicsv_rd(void)
{
char *buff;
if (unicsv_fieldsep == NULL) return;
-
+
while ((buff = gbfgetstr(fin))) {
buff = lrtrim(buff);
if ((*buff == '\0') || (*buff == '#')) continue;
{
if (str && *str) {
char *cout, *cx;
-
+
cout = strenquote(str, UNICSV_QUOT_CHAR);
while ((cx = strstr(cout, "\r\n"))) {
*cx++ = ',';
lrtrim(cx);
}
-
+
gbfprintf(fout, "%s%s", unicsv_fieldsep, cout);
xfree(cout);
}
struct tm tm;
time_t time = atime;
char buf[32] = "";
-
+
if (time) {
if (opt_utc) {
time += atoi(opt_utc) * SECONDS_PER_HOUR;
tm = *gmtime(&time);
}
else tm = *localtime(&time);
- snprintf(buf, sizeof(buf), "%04d/%02d/%02d %02d:%02d:%02d",
+ snprintf(buf, sizeof(buf), "%04d/%02d/%02d %02d:%02d:%02d",
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
tm.tm_hour, tm.tm_min, tm.tm_sec);
}
#define FIELD_USED(a) (gb_getbit(&unicsv_outp_flags, a))
-static void
+static void
unicsv_waypt_enum_cb(const waypoint *wpt)
{
char *shortname;
shortname = (wpt->shortname) ? wpt->shortname : "";
gmsd = GMSD_FIND(wpt);
-
+
if (*shortname) gb_setbit(&unicsv_outp_flags, fld_shortname);
if (wpt->altitude != unknown_alt) gb_setbit(&unicsv_outp_flags, fld_altitude);
if (wpt->icon_descr && *wpt->icon_descr) gb_setbit(&unicsv_outp_flags, fld_symbol);
if WAYPT_HAS(wpt, speed) gb_setbit(&unicsv_outp_flags, fld_speed);
if WAYPT_HAS(wpt, proximity) gb_setbit(&unicsv_outp_flags, fld_proximity);
if WAYPT_HAS(wpt, temperature) gb_setbit(&unicsv_outp_flags, fld_temperature);
-
+
if (gmsd) {
if GMSD_HAS(addr) gb_setbit(&unicsv_outp_flags, fld_garmin_addr);
if GMSD_HAS(city) gb_setbit(&unicsv_outp_flags, fld_garmin_city);
if GMSD_HAS(state) gb_setbit(&unicsv_outp_flags, fld_garmin_state);
if GMSD_HAS(facility) gb_setbit(&unicsv_outp_flags, fld_garmin_facility);
}
-
+
#ifdef UNICSV_GC_READY
if (! waypt_empty_gc_data(wpt)) {
const geocache_data *gc_data = wpt->gc_data;
-
+
if (gc_data->id) gb_setbit(&unicsv_outp_flags, fld_gc_id);
if (gc_data->type) gb_setbit(&unicsv_outp_flags, fld_gc_type);
if (gc_data->container) gb_setbit(&unicsv_outp_flags, fld_gc_container);
#endif
}
-static void
+static void
unicsv_waypt_disp_cb(const waypoint *wpt)
{
double lat, lon, alt;
shortname = (wpt->shortname) ? wpt->shortname : "";
gmsd = GMSD_FIND(wpt);
-
+
if (unicsv_datum_idx == DATUM_WGS84) {
lat = wpt->latitude;
lon = wpt->longitude;
}
gbfprintf(fout, "%d%s", unicsv_waypt_ct, unicsv_fieldsep);
-
+
switch(unicsv_grid_idx) {
case grid_lat_lon_ddd:
cout = pretty_deg_format(lat, lon, 'm', unicsv_fieldsep, 0);
gbfputs(cout, fout);
break;
-
+
case grid_lat_lon_dms: {
char *sep, *tmp;
cout = pretty_deg_format(lat, lon, 's', unicsv_fieldsep, 0);
if (! GPS_Math_WGS84_To_UKOSMap_M(wpt->latitude, wpt->longitude, &east, &north, map))
unicsv_fatal_outside(wpt);
gbfprintf(fout, "%s%s%5.0f%s%5.0f",
- map, unicsv_fieldsep,
- east, unicsv_fieldsep,
+ map, unicsv_fieldsep,
+ east, unicsv_fieldsep,
north);
break;
}
&east, &north, &zone, &zonec, unicsv_datum_idx))
unicsv_fatal_outside(wpt);
gbfprintf(fout, "%02d%s%c%s%.0f%s%.0f",
- zone, unicsv_fieldsep,
+ zone, unicsv_fieldsep,
zonec, unicsv_fieldsep,
- east, unicsv_fieldsep,
+ east, unicsv_fieldsep,
north);
break;
}
case grid_swiss: {
double north, east;
-
+
if (! GPS_Math_WGS84_To_Swiss_EN(wpt->latitude, wpt->longitude, &east, &north))
unicsv_fatal_outside(wpt);
gbfprintf(fout, "%.f%s%.f",
gbfprintf(fout, "%.*f%s%.*f", llprec, lat, unicsv_fieldsep, llprec, lon);
break;
}
-
+
if (cout) xfree(cout);
if FIELD_USED(fld_shortname) unicsv_print_str(shortname);
struct tm tm;
char buf[32];
time_t time = wpt->creation_time;
-
+
if (opt_utc) {
time += atoi(opt_utc) * SECONDS_PER_HOUR;
tm = *gmtime(&time);
struct tm tm;
char buf[32], msec[12];
time_t time = wpt->creation_time;
-
+
if (opt_utc) {
time += atoi(opt_utc) * SECONDS_PER_HOUR;
tm = *gmtime(&time);
if (wpt->microseconds > 0) {
int len = 6;
int ms = wpt->microseconds;
-
+
while (len && (ms % 10 == 0)) {
ms /= 10;
len--;
#ifdef UNICSV_GC_READY
if (waypt_empty_gc_data(wpt)) gc_data = NULL;
else gc_data = wpt->gc_data;
-
+
if FIELD_USED(fld_gc_id) {
gbfputs(unicsv_fieldsep, fout);
if (gc_data && gc_data->id) gbfprintf(fout, "%d", gc_data->id);
if (opt_grid != NULL) {
int i;
-
+
if (sscanf(opt_grid, "%d", &i)) {
unicsv_grid_idx = (grid_type) i;
if ((unicsv_grid_idx < GRID_INDEX_MIN) || (unicsv_grid_idx > GRID_INDEX_MAX))
}
else unicsv_grid_idx = gt_lookup_grid_type(opt_grid, MYNAME);
}
-
+
if (unicsv_grid_idx == grid_bng)
/* force datum to "Ord Srvy Grt Britn" / OSGB36 */
/* ! ignore parameter "Datum" ! */
unicsv_datum_idx = DATUM_WGS84; /* internal, becomes CH1903 */
else
unicsv_datum_idx = gt_lookup_datum_index(opt_datum, MYNAME);
-
+
llprec = atoi(opt_prec);
}
route_disp_all(NULL, NULL, unicsv_waypt_enum_cb);
break;
case posndata:
- fatal(MYNAME ": Realtime positioning not supported.\n");
+ fatal(MYNAME ": Realtime positioning not supported.\n");
}
gbfprintf(fout, "No%s", unicsv_fieldsep);
switch(unicsv_grid_idx) {
- case grid_bng:
+ case grid_bng:
/* indexed parameters doesn't work under __win32__ (mingw)
gbfprintf(fout, "BNG-Zone%1$sBNG-East%1$sBNG-North", unicsv_fieldsep);
*/
gbfprintf(fout, "BNG-Zone%sBNG-East%sBNG-North",
unicsv_fieldsep, unicsv_fieldsep);
break;
- case grid_utm:
+ case grid_utm:
/* indexed parameters doesn't work under __win32__ (mingw)
gbfprintf(fout, "BNG-Zone%1$sBNG-East%1$sBNG-North", unicsv_fieldsep);
*/
gbfprintf(fout, "UTM-Zone%sUTM-Ch%sUTM-East%sUTM-North",
unicsv_fieldsep, unicsv_fieldsep, unicsv_fieldsep);
break;
- case grid_swiss:
+ case grid_swiss:
gbfprintf(fout, "Swiss-East%sSwiss-North",
unicsv_fieldsep);
break;
- default:
+ default:
gbfprintf(fout, "Latitude%sLongitude", unicsv_fieldsep);
}
if FIELD_USED(fld_gc_placer) gbfprintf(fout, "%sPlacer", unicsv_fieldsep);
if FIELD_USED(fld_gc_placer_id) gbfprintf(fout, "%sPlacer ID", unicsv_fieldsep);
if FIELD_USED(fld_gc_hint) gbfprintf(fout, "%sHint", unicsv_fieldsep);
-#endif
+#endif
if (opt_format) gbfprintf(fout, "%sFormat", unicsv_fieldsep);
if (opt_filename) gbfprintf(fout, "%sFilename", unicsv_fieldsep);
-
+
gbfputs(UNICSV_LINE_SEP, fout);
switch(global_opts.objective) {
FF_CAP_RW_ALL,
unicsv_rd_init,
unicsv_wr_init,
- unicsv_rd_deinit,
+ unicsv_rd_deinit,
unicsv_wr_deinit,
unicsv_rd,
unicsv_wr,